package com.lefevre.cms.service.message.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lefevre.cms.bean.QueryResult;
import com.lefevre.cms.bean.message.PrivateMessage;
import com.lefevre.cms.mapper.PrivateMessageMapper;
import com.lefevre.cms.service.besa.DaoSupport;
import com.lefevre.cms.service.message.PrivateMessageService;
import com.lefevre.cms.utils.ObjectConversion;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.persistence.Query;
import java.util.ArrayList;
import java.util.List;

/**
 * 私信
 *
 * @author Lefevre
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class PrivateMessageServiceImpl extends DaoSupport<PrivateMessage> implements PrivateMessageService {

    @Resource
    private PrivateMessageMapper baseMapper;

    /**
     * 保存私信
     * 先由privateMessageManage.createPrivateMessageObject();方法生成对象再保存
     *
     * @param sender_privateMessage   私信发送者
     * @param receiver_privateMessage 私信接收者
     */
    public void savePrivateMessage(Object sender_privateMessage, Object receiver_privateMessage) {
        baseMapper.insert((PrivateMessage) sender_privateMessage);
        baseMapper.insert((PrivateMessage) receiver_privateMessage);
    }


    /**
     * 根据用户Id查询私信列表分页(后台原生SQL查询)
     *
     * @param userId     用户Id
     * @param firstIndex 索引开始,即从哪条记录开始
     * @param maxResult  获取多少条数据
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public QueryResult<PrivateMessage> findPrivateMessageByUserId(Long userId, int firstIndex, int maxResult) {
        QueryResult<PrivateMessage> qr = new QueryResult<>();

        String sql = "select ANY_VALUE(t1.id) as id, ANY_VALUE(t1.userId) as userId, ANY_VALUE(t1.friendUserId) as friendUserId, ANY_VALUE(t1.senderUserId) as senderUserId, ANY_VALUE(t1.receiverUserId) as receiverUserId, ANY_VALUE(t1.messageContent) as messageContent, ANY_VALUE(t1.status) as status, ANY_VALUE(t1.sendTimeFormat) as sendTimeFormat, ANY_VALUE(t1.readTimeFormat) as readTimeFormat from privatemessage t1, (select o.friendUserId as friendUserId, max(o.sendTimeFormat) as max_sendTimeFormat from privatemessage o where o.userId=? GROUP BY o.friendUserId) as t2 where t1.friendUserId=t2.friendUserId and t1.sendTimeFormat=t2.max_sendTimeFormat GROUP BY t1.friendUserId ORDER BY ANY_VALUE(t1.sendTimeFormat) desc";

        Query query = em.createNativeQuery(sql);
        query.setParameter(1, userId);


        //索引开始,即从哪条记录开始
        query.setFirstResult(firstIndex);
        //获取多少条数据
        query.setMaxResults(maxResult);

        List<PrivateMessage> privateMessageList = new ArrayList<>();
        List<Object[]> objectList = query.getResultList();

        if (objectList != null && objectList.size() > 0) {
            for (Object[] object : objectList) {
                PrivateMessage privateMessage = new PrivateMessage();
                privateMessage.setId(ObjectConversion.conversion(object[0], ObjectConversion.STRING));
                privateMessage.setUserId(ObjectConversion.conversion(object[1], ObjectConversion.LONG));
                privateMessage.setFriendUserId(ObjectConversion.conversion(object[2], ObjectConversion.LONG));
                privateMessage.setSenderUserId(ObjectConversion.conversion(object[3], ObjectConversion.LONG));
                privateMessage.setReceiverUserId(ObjectConversion.conversion(object[4], ObjectConversion.LONG));
                privateMessage.setMessageContent(ObjectConversion.conversion(object[5], ObjectConversion.STRING));
                privateMessage.setStatus(ObjectConversion.conversion(object[6], ObjectConversion.INTEGER));
                privateMessage.setSendTimeFormat(ObjectConversion.conversion(object[7], ObjectConversion.LONG));
                privateMessage.setReadTimeFormat(ObjectConversion.conversion(object[8], ObjectConversion.LONG));
                privateMessageList.add(privateMessage);
            }
        }

        //把查询结果设进去
        qr.setResultlist(privateMessageList);

        query = em.createNativeQuery("select count(1) c from (select count(1) from privatemessage o where o.userId=? GROUP BY o.friendUserId ) c1");
        query.setParameter(1, userId);
        long lCount = 0L;
        for (Object o : query.getResultList()) {
            lCount += Long.parseLong(o.toString());
        }

        //获取总记录数
        qr.setTotalrecord(lCount);

        return qr;
    }

    /**
     * 根据用户Id查询私信列表分页(前台原生SQL查询)
     *
     * @param userId     用户Id
     * @param status     状态
     * @param firstIndex 索引开始,即从哪条记录开始
     * @param maxResult  获取多少条数据
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public QueryResult<PrivateMessage> findPrivateMessageByUserId(Long userId, Integer status, int firstIndex, int maxResult) {
        QueryResult<PrivateMessage> qr = new QueryResult<PrivateMessage>();

        String sql = "select ANY_VALUE(t1.id) as id, ANY_VALUE(t1.userId) as userId, ANY_VALUE(t1.friendUserId) as friendUserId, ANY_VALUE(t1.senderUserId) as senderUserId, ANY_VALUE(t1.receiverUserId) as receiverUserId, ANY_VALUE(t1.messageContent) as messageContent, ANY_VALUE(t1.status) as status, ANY_VALUE(t1.sendTimeFormat) as sendTimeFormat, ANY_VALUE(t1.readTimeFormat) as readTimeFormat from privatemessage t1, (select o.friendUserId as friendUserId, max(o.sendTimeFormat) as max_sendTimeFormat from privatemessage o where o.userId=? and o.status <?  GROUP BY o.friendUserId) as t2 where t1.friendUserId=t2.friendUserId and t1.sendTimeFormat=t2.max_sendTimeFormat GROUP BY t1.friendUserId ORDER BY ANY_VALUE(t1.status) asc, ANY_VALUE(t1.sendTimeFormat) desc";


        Query query = em.createNativeQuery(sql);

        query.setParameter(1, userId);
        query.setParameter(2, status);


        //索引开始,即从哪条记录开始
        query.setFirstResult(firstIndex);
        //获取多少条数据
        query.setMaxResults(maxResult);

        List<PrivateMessage> privateMessageList = new ArrayList<>();
        List<Object[]> objectList = query.getResultList();

        if (objectList != null && objectList.size() > 0) {
            for (Object[] object : objectList) {
                PrivateMessage privateMessage = new PrivateMessage();
                privateMessage.setId(ObjectConversion.conversion(object[0], ObjectConversion.STRING));
                privateMessage.setUserId(ObjectConversion.conversion(object[1], ObjectConversion.LONG));
                privateMessage.setFriendUserId(ObjectConversion.conversion(object[2], ObjectConversion.LONG));
                privateMessage.setSenderUserId(ObjectConversion.conversion(object[3], ObjectConversion.LONG));
                privateMessage.setReceiverUserId(ObjectConversion.conversion(object[4], ObjectConversion.LONG));
                privateMessage.setMessageContent(ObjectConversion.conversion(object[5], ObjectConversion.STRING));
                privateMessage.setStatus(ObjectConversion.conversion(object[6], ObjectConversion.INTEGER));
                privateMessage.setSendTimeFormat(ObjectConversion.conversion(object[7], ObjectConversion.LONG));
                privateMessage.setReadTimeFormat(ObjectConversion.conversion(object[8], ObjectConversion.LONG));
                privateMessageList.add(privateMessage);
            }
        }

        //把查询结果设进去
        qr.setResultlist(privateMessageList);

        query = em.createNativeQuery("select count(1) c from (select count(1) from privatemessage o where o.userId=? and o.status <? GROUP BY o.friendUserId ) c1");
        query.setParameter(1, userId);
        query.setParameter(2, status);
        Long lCount = 0L;
        for (Object o : query.getResultList()) {
            lCount += Long.parseLong(o.toString());
        }

        //获取总记录数
        qr.setTotalrecord(lCount);

        return qr;
    }


    /**
     * 根据用户Id查询私信对话分页
     *
     * @param userId       用户Id
     * @param friendUserId 对方用户Id
     * @param status       状态
     * @param firstIndex   索引开始,即从哪条记录开始
     * @param maxResult    获取多少条数据
     * @param sort         排序 1.aes 2.desc
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public QueryResult<PrivateMessage> findPrivateMessageChatByUserId(Long userId, Long friendUserId, Integer status, int firstIndex, int maxResult, Integer sort) {
        QueryResult<PrivateMessage> qr = new QueryResult<>();

        LambdaQueryWrapper<PrivateMessage> wrapper = new LambdaQueryWrapper<>();

        if (status != null) {
            wrapper.lt(PrivateMessage::getStatus, 100);
        }
        if (sort.equals(1)) {
            wrapper.orderByAsc(PrivateMessage::getSendTimeFormat);
        } else {
            wrapper.orderByDesc(PrivateMessage::getSendTimeFormat);
        }
        wrapper.eq(PrivateMessage::getUserId, userId);
        wrapper.eq(PrivateMessage::getFriendUserId, friendUserId);

        Page<PrivateMessage> privateMessagePage = baseMapper.selectPage(new Page<>(firstIndex, maxResult), wrapper);

        qr.setResultlist(privateMessagePage.getRecords());
        qr.setTotalrecord(privateMessagePage.getTotal());
        return qr;
    }

    /**
     * 根据用户Id查询私信对话分页总数
     *
     * @param userId       用户Id
     * @param friendUserId 对方用户Id
     * @param status       状态
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public Long findPrivateMessageChatCountByUserId(Long userId, Long friendUserId, Integer status) {
        LambdaQueryWrapper<PrivateMessage> wrapper = new LambdaQueryWrapper<>();
        if (status != null) {
            wrapper.lt(PrivateMessage::getStatus, 100);
        }
        wrapper.eq(PrivateMessage::getUserId, userId);
        wrapper.eq(PrivateMessage::getFriendUserId, friendUserId);
        return baseMapper.selectCount(wrapper);
    }

    /**
     * 根据用户Id查询未读私信数量
     *
     * @param userId 用户Id
     * @return
     */
    @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED)
    public Long findUnreadPrivateMessageByUserId(Long userId) {
        return baseMapper.selectCount(new LambdaQueryWrapper<PrivateMessage>()
                .eq(PrivateMessage::getUserId, userId)
                .eq(PrivateMessage::getStatus, 10));
    }


    /**
     * 设置私信状态为已读
     *
     * @param userId               用户Id
     * @param privateMessageIdList 私信Id集合
     */
    public Integer updatePrivateMessageStatus(Long userId, List<String> privateMessageIdList) {
        return baseMapper.update(null, new LambdaUpdateWrapper<PrivateMessage>()
                .set(PrivateMessage::getStatus, 20)
                .set(PrivateMessage::getReadTimeFormat, System.currentTimeMillis())
                .in(PrivateMessage::getId, privateMessageIdList)
                .lt(PrivateMessage::getStatus, 20));
    }


    /**
     * 软删除私信
     *
     * @param userId       用户Id
     * @param friendUserId 对方用户Id
     */
    public Integer softDeletePrivateMessage(Long userId, Long friendUserId) {
        return baseMapper.softDelete(userId, friendUserId);
    }


    /**
     * 删除私信
     *
     * @param userId       用户Id
     * @param friendUserId 对方用户Id
     */
    public Integer deletePrivateMessage(Long userId, Long friendUserId) {
        return baseMapper.delete(new LambdaUpdateWrapper<PrivateMessage>()
                .eq(PrivateMessage::getUserId, userId)
                .eq(PrivateMessage::getFriendUserId, friendUserId));
    }

    /**
     * 删除用户所有私信
     *
     * @param userIdList 用户Id集合
     */
    public Integer deleteUserPrivateMessage(List<Long> userIdList) {
        int j = baseMapper.delete(new LambdaUpdateWrapper<PrivateMessage>().in(PrivateMessage::getUserId, userIdList));
        j += baseMapper.delete(new LambdaUpdateWrapper<PrivateMessage>().in(PrivateMessage::getFriendUserId, userIdList));
        return j;
    }

    /**
     * 还原被用户删除的私信
     *
     * @param privateMessageId 私信Id
     */
    public Integer reductionPrivateMessage(String privateMessageId) {
        return baseMapper.restore(privateMessageId);
    }

}
